import { FormatResponse, cryptoStore } from './cryptoFactory'
import { FHOST, ASK_HOST, INVITE_FROM_TOKEN, USER_ACCESS, UP_HOST } from '../constants/sitevars'
import { isInvitationUsable } from './shareConfig'
import { formatUserInfo } from './wxlogin-queue'
const accInfo = wx.getAccountInfoSync()
const env = accInfo.miniProgram.envVersion

const httpConfig = {
  baseData: {
    // version: 1.1
  },
  code: {
    success: 0,
    access_token_missing: 400,
    login: 401,
    updateForce: 301,
    update: 302,
    hide: 503,
    error: 500
  }
}


function setHosturl() {
  const upHost = UP_HOST;
  const hosturl = FHOST[env];
  const askHost = ASK_HOST[env];
  this.globalData.upHost = upHost;
  this.globalData.hosturl = hosturl;
  this.globalData.askHost = askHost;
}
const gettoken = () => {
  return new Promise(async (resolve, reject) => {
    const { token } = formatUserInfo()
    if (token) {
      resolve()
    } else {
      setTimeout(async () => {
        await gettoken()
        resolve()
      }, 1000);
    }
  })
}
/**
 *
 * @param {*} params.type
 * @param {*} params.url
 * @param {*} params.method
 * @param {*} params.data
 * @param {*} params.dataType
 * @param {*} params.success 回调
 * @param {*} params.error 回调
 * @param {*} params.fail 回调
 * @GlobalTip globalData.hasLogined 判断是否登录
 * @GlobalTip globalData.callbackWithCode 有code后的回调参数list
 * @this 已将request的apply指向app.js
 *
 */
async function request(params = {}) {
  return new Promise(async (resolve, reject) => {
    const { needCode = true, loading = true } = params
    if (needCode && !this.globalData.hasLogined) {
      // 登录态失效，或者需要code，则放入等待执行
      await gettoken()
    }

    if (params.type) {
      switch (params.type.toLowerCase()) {
        case 'json':
          params.type = 'application/json'
          break
        case 'form':
          params.type = 'application/x-www-form-urlencoded'
          break
        default:
      }
    }
    //默认使用json，除非按上面的switch传入指定的content-type
    params.type = params.type || 'application/json'
    //预处理是绝对地址还是相对地址，后者需拼接请求基础参数的API根地址
    if (params.url.indexOf('https://') < 0 && params.url.indexOf('http://') < 0) {
      const apiUrl = FHOST[env]
      params.url = apiUrl + (params.url || '')
    }
    //是否显示Loading 默认不显示Loading
    if (loading) {
      wx.showLoading()
    }
    const header = params.header || {
      'content-type': params.type
    }
    const currentPages = getCurrentPages()
    if (currentPages.length) {
      const { options } = currentPages[currentPages.length - 1]
      if (isInvitationUsable(params.url)) {
        params.data = params.data || {}
        params.data[INVITE_FROM_TOKEN] = options[INVITE_FROM_TOKEN]
        console.log('withCensus -> params.data：', params.data)
      }
    }

    //读取本地缓存的access_token
    const { token } = cryptoStore.getStorageSync(USER_ACCESS) || {}
    //设置access_token到基础请求参数
    token && (header.token = token)
    wx.request({
      url: params.url,
      //默认使用application/json基础header，除非完全自定义header
      header,
      //默认使用POST请求，除非指定method
      method: params.method || 'POST',
      //将基础请求参数和本次请求参数合并
      data: {
        ...this.globalData.httpConfig.baseData,
        ...(params.data || {})
      },
      //固定返回数据格式 默认json 除非指定其他
      dataType: params.dataType || 'json',
      success: (res) => {
        // decode response
        res = FormatResponse(res)
        try {
          switch (res.data.code) {
            case this.globalData.httpConfig.code.success:
              resolve(res.data?.data)
              break;

            case this.globalData.httpConfig.code.access_token_missing:
            case this.globalData.httpConfig.code.login:
              //需要登录
              if (params.login) {
                params.login(res.data)
              } else {
                wx.showModal({
                  title: '身份验证失败',
                  content: res.data.msg,
                  showCancel: false,
                  success: () => {
                    // this.showLogin()
                  }
                })
              }
              break;

            case this.globalData.httpConfig.code.hide:
              wx.reLaunch({
                url: '/pages/home/home'
              })
              break;
            default:
              //解析其他状态码
              wx.showModal({
                title: '操作失败(' + res.data.code + ')',
                content: res.data.msg,
                showCancel: false
              })
          }
        } catch (e) {
          //解析可能发生的异常
          reject(res)
          wx.showModal({
            title: '数据错误',
            content: '解析服务器数据失败，请稍候再试！',
            showCancel: false
          })
        }
      },
      fail: (res) => {
        //解析可能发生的异常
        reject(res)
        wx.showModal({
          title: '连接失败',
          content: '网络连接失败，请稍候再试！',
          showCancel: false
        })
      },
      complete: () => {
        wx.hideLoading()
      }
    })
  })
}

export {
  httpConfig,
  setHosturl,
}

export default request
